﻿/**
 ** @作者:	   王桂龙 QQ731513122
 ** @日期:	   2017年10月

 ** @简介:     IBHXJZOOM接口和Zoom接口扩展函数

   *****1.在control类中加入下列代码即可实现IBHXJZoom所规定的属性

        #region 继承于ZOOM接口的属性和方法
        private Point _OriginPoint = new Point(0, 0);
        [Description("原点(慎用,在足够了解BHXJZoom的情况下使用)"), Category("BHXJZoom")]
        /// <summary>
        /// 原点
        /// </summary>
        public Point OriginPoint
        {
            get
            { return this._OriginPoint; }
            set
            {
                if (this._OriginPoint != value)
                {
                    this._OriginPoint = value;
                    if (DesignMode)
                        this.IniLocation = this.BHXJGetIniLocationInDesignMode();
                }
            }
        }
        private bool _AutoOrigin = false;
        [Description("自动更改原点模式(只在设计模式下有用)"), Category("BHXJZoom")]
        /// <summary>
        /// 自动更改原点模式(只在设计模式下有用)
        /// </summary>
        public bool AutoOrigin
        {
            get
            {
                return this._AutoOrigin;
            }
            set
            {
                if (this._AutoOrigin != value)
                {
                    this._AutoOrigin = value;
                    if (DesignMode)
                    {
                        if (this.AutoOrigin)
                        {
                            this.OriginPoint = this.Location;
                        }
                        else
                        {
                            this.OriginPoint = new Point(0, 0);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 初始尺寸
        /// </summary>
        [Browsable(false)]
        public Size IniSize { get; set; }
        /// <summary>
        /// 初始位置
        /// </summary>
        [Browsable(false)]
        public Point IniLocation { get; set; }
        /// <summary>
        /// 初始字体
        /// </summary>
        [Browsable(false)]
        public Font IniFont { get; set; }
        #endregion

   *****2.在设计模式下响应control的SizeChanged  FontChanged LocationChanged 事件记录控件的尺寸，字体大小和位置。      
        在control的构造函数中加入该代码段即可实现
        #region 设计时,变化事件
        if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
        {
            //设计时事件
            this.SizeChanged += new EventHandler(this.BHXJ_SizeChangedInDesignMode);
            this.FontChanged += new EventHandler(this.BHXJ_FontChangedInDesignMode);
            this.LocationChanged += new EventHandler(this.BHXJ_LocationChangedInDesignMode);
        }
        #endregion


   *****3.在容器类控件中在SizeChanged事件响应中，调用EntendZoom函数来缩放Controls成员中继承IBHXJZOOM接口的控件
          具体可以参考BHXJContainer

 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Reflection;
//using System.Runtime;

namespace BHXJDOTNET
{
    public interface IBHXJZOOM
    {
        /// <summary>
        /// 原点
        /// </summary>
        Point OriginPoint { get; set; }
        /// <summary>
        /// 自动更改原点
        /// </summary>
        bool AutoOrigin { get; set; }

        /// <summary>
        /// 初始尺寸
        /// </summary>
        Size IniSize { get; set; }

        /// <summary>
        ///  初始位置
        /// </summary>
        Point IniLocation { get; set; }

        /// <summary>
        /// 初始字体
        /// </summary>
        Font IniFont { get; set; }
    }

    /// <summary>
    /// ZOOM接口扩展函数类
    /// </summary>
    public static class EntendZoom
    {
        //public static void wglZOOM<T>(this T bhxjzoom) 
        //    where T : IBHXJZOOM
        //{

        //}
        /// <summary>
        /// DesignMode属性Get函数的MethodInfo
        /// </summary>
        public static MethodInfo DesignModeGetMeth = EntendZoom.DesignModeGetInfo();

        /// <summary>
        /// 尺寸缩放xy
        /// </summary>
        /// <param name="bhxjzoom"></param>
        /// <param name="scalex"></param>
        /// <param name="scaley"></param>
        public static void BHXJSizeZoom(this IBHXJZOOM bhxjzoom, double scalex, double scaley)
        {
            Control cachecontrol = bhxjzoom as Control;
            if (cachecontrol != null)
            {
                cachecontrol.Size = new Size((int)(bhxjzoom.IniSize.Width * scalex), (int)(bhxjzoom.IniSize.Height * scaley));
            }
        }
        /// <summary>
        /// 尺寸缩放
        /// </summary>
        /// <param name="bhxjzoom"></param>
        /// <param name="scale"></param>
        public static void BHXJSizeZoom(this IBHXJZOOM bhxjzoom, double scale)
        {
            Control cachecontrol = bhxjzoom as Control;
            if (cachecontrol != null)
            {
                int w = (int)(bhxjzoom.IniSize.Width * scale);
                w = (w > 0) ? w : 1;
                int h = (int)(bhxjzoom.IniSize.Height * scale);
                h = (h > 0) ? h : 1;
                cachecontrol.Size = new Size(w, h);
                //cachecontrol.Size = new Size((int)(bhxjzoom.IniSize.Width * scale), (int)(bhxjzoom.IniSize.Height * scale));             
            }
            
        }
        /// <summary>
        /// 字体缩放
        /// </summary>
        /// <param name="bhxjzoom"></param>
        /// <param name="scale"></param>
        public static void BHXJFontZoom(this IBHXJZOOM bhxjzoom, double scale)
        {
            Control cachecontrol = bhxjzoom as Control;
            if (cachecontrol != null)
            {
                //BHXJDOTNET.NEW.BHXJComPass cp = bhxjzoom as BHXJDOTNET.NEW.BHXJComPass;
                //if (cp != null)
                //{
                //    return;
                //}

                float size = (float)(bhxjzoom.IniFont.Size * scale);

                size = (size > 0) ? size : 1;
                Font f = new Font(cachecontrol.Font.FontFamily, size, cachecontrol.Font.Style);
                try
                {               
                    cachecontrol.Font = f;
                }
                catch//(Exception ex)
                { }

            }
        }
        /// <summary>
        /// 位置缩放xy
        /// </summary>
        /// <param name="bhxjzoom"></param>
        /// <param name="scalex"></param>
        /// <param name="scaley"></param>
        public static void BHXJLocationZoom(this IBHXJZOOM bhxjzoom, double scalex, double scaley)
        {
            Control cachecontrol = bhxjzoom as Control;
            if (cachecontrol != null)
            {
                cachecontrol.Location = new Point((int)(bhxjzoom.IniLocation.X * scalex) + bhxjzoom.OriginPoint.X, (int)(bhxjzoom.IniLocation.Y * scaley) + bhxjzoom.OriginPoint.Y);
            }
        }
        /// <summary>
        /// 位置缩放
        /// </summary>
        /// <param name="bhxjzoom"></param>
        /// <param name="scalex"></param>
        /// <param name="scaley"></param>
        public static void BHXJLocationZoom(this IBHXJZOOM bhxjzoom, double scale)
        {
            Control cachecontrol = bhxjzoom as Control;
            if (cachecontrol != null)
            {
                cachecontrol.Location = new Point((int)(bhxjzoom.IniLocation.X * scale) + bhxjzoom.OriginPoint.X, (int)(bhxjzoom.IniLocation.Y * scale) + bhxjzoom.OriginPoint.Y);
            }
        }

        ///// <summary>
        ///// 获取初始位置
        ///// </summary>
        ///// <param name="bhxjzoom"></param>
        ///// <param name="scalex"></param>
        ///// <param name="scaley"></param>
        //public static Point BHXJGetIniLocation(this IBHXJZOOM bhxjzoom)
        //{
        //    if (bhxjzoom is Control)
        //    {
        //        Control cachecontrol = bhxjzoom as Control;
        //        return new Point(cachecontrol.Location.X - bhxjzoom.OriginPoint.X, cachecontrol.Location.Y - bhxjzoom.OriginPoint.Y);
        //    }
        //    else
        //    {
        //        return new Point();
        //    }
        //}


        public static MethodInfo DesignModeGetInfo()
        {
            Type t = typeof(Component);
            PropertyInfo[] finfos = t.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (PropertyInfo finfo in finfos)
            {
                if (finfo.Name == "DesignMode")
                {
                    return finfo.GetGetMethod(true);
                }
            }
            return null;
        }

        /// <summary>
        /// 获取初始位置(设计时用)
        /// </summary>
        /// <param name="bhxjzoom"></param>
        /// <param name="scalex"></param>
        /// <param name="scaley"></param>
        public static Point BHXJGetIniLocationInDesignMode(this IBHXJZOOM bhxjzoom)
        {
            Control cachecontrol;
            Component comp;
            bool designmode = false;
            if (bhxjzoom is Control)
                cachecontrol = bhxjzoom as Control;
            else
                return new Point();
            if (bhxjzoom is Component)
                comp = bhxjzoom as Component;
            else
                return new Point();
            //获取DesignMode
            object obj = DesignModeGetMeth.Invoke(comp, null);
            designmode = (bool)obj;

            if (designmode)
                return new Point(cachecontrol.Location.X - bhxjzoom.OriginPoint.X, cachecontrol.Location.Y - bhxjzoom.OriginPoint.Y);
            else
                return new Point();
        }

        /// <summary>
        /// 尺寸变化处理函数(设计时用)
        /// </summary>
        /// <param name="bhxjzoom"></param>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void BHXJ_SizeChangedInDesignMode(this IBHXJZOOM bhxjzoom, object sender, EventArgs e)
        {
            Control cachecontrol;
            Component comp;
            bool designmode = false;
            if (bhxjzoom is Control)
                cachecontrol = bhxjzoom as Control;
            else
                return;
            if (bhxjzoom is Component)
                comp = bhxjzoom as Component;
            else
                return;
            //获取DesignMode
            object obj = DesignModeGetMeth.Invoke(comp, null);
            designmode = (bool)obj;

            if (designmode)
            {
                bhxjzoom.IniSize = cachecontrol.Size;
            }
        }

        /// <summary>
        /// 字体变化处理函数(设计时用)
        /// </summary>
        /// <param name="bhxjzoom"></param>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void BHXJ_FontChangedInDesignMode(this IBHXJZOOM bhxjzoom, object sender, EventArgs e)
        {
            Control cachecontrol;
            Component comp;
            bool designmode = false;
            if (bhxjzoom is Control)
                cachecontrol = bhxjzoom as Control;
            else
                return;
            if (bhxjzoom is Component)
                comp = bhxjzoom as Component;
            else
                return;
            //获取DesignMode
            object obj = DesignModeGetMeth.Invoke(comp, null);
            designmode = (bool)obj;

            if (designmode)
            {
                bhxjzoom.IniFont = cachecontrol.Font;
            }
        }

        /// <summary>
        /// 位置变化处理函数(设计时用)
        /// </summary>
        /// <param name="bhxjzoom"></param>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void BHXJ_LocationChangedInDesignMode(this IBHXJZOOM bhxjzoom, object sender, EventArgs e)
        {
            Control cachecontrol;
            Component comp;
            bool designmode = false;
            if (bhxjzoom is Control)
                cachecontrol = bhxjzoom as Control;
            else
                return;
            if (bhxjzoom is Component)
                comp = bhxjzoom as Component;
            else
                return;
            //获取DesignMode
            object obj = DesignModeGetMeth.Invoke(comp, null);
            designmode = (bool)obj;

            if (designmode)
            {
                if (bhxjzoom.AutoOrigin)
                {
                    bhxjzoom.OriginPoint = cachecontrol.Location;
                }
                bhxjzoom.IniLocation = bhxjzoom.BHXJGetIniLocationInDesignMode();
            }
        }
    }
}
